package org.example.backend.service.impl;

import cn.hutool.core.util.RandomUtil;
import lombok.extern.slf4j.Slf4j;
import org.example.backend.service.EmailService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Service;

import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;
import java.util.Date;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 邮件服务实现类
 */
@Service
@Slf4j
public class EmailServiceImpl implements EmailService {

    @Autowired
    private JavaMailSender mailSender;

    @Value("${spring.mail.username}")
    private String from;

    @Value("${qq.email.subject}")
    private String subject;

    @Value("${qq.email.template}")
    private String template;

    @Value("${qq.email.code-expire-minutes}")
    private int expireMinutes;

    @Value("${qq.email.code-length}")
    private int codeLength;

    @Value("${qq.email.code-type}")
    private String codeType;

    // 使用内存缓存存储验证码，实际项目中可以使用Redis等缓存
    private final Map<String, CodeInfo> codeMap = new ConcurrentHashMap<>();

    @Override
    public String sendVerificationCode(String to) {
        // 生成验证码
        String code;
        if ("NUMERIC".equals(codeType)) {
            code = RandomUtil.randomNumbers(codeLength);
        } else if ("ALPHABETIC".equals(codeType)) {
            code = RandomUtil.randomString(codeLength);
        } else {
            code = RandomUtil.randomString(codeLength);
        }

        try {
            MimeMessage message = mailSender.createMimeMessage();
            MimeMessageHelper helper = new MimeMessageHelper(message, true);
            helper.setFrom(from);
            helper.setTo(to);
            helper.setSubject(subject);
            // 使用配置的模板，替换验证码和过期时间
            String content = String.format(template, code, expireMinutes);
            helper.setText(content, true);
            mailSender.send(message);
            
            // 保存验证码信息
            codeMap.put(to, new CodeInfo(code, new Date()));
            log.info("发送验证码邮件成功，接收邮箱：{}", to);
            return code;
        } catch (MessagingException e) {
            log.error("发送验证码邮件失败", e);
            throw new RuntimeException("发送验证码邮件失败", e);
        }
    }

    @Override
    public boolean verifyCode(String email, String code) {
        CodeInfo codeInfo = codeMap.get(email);
        if (codeInfo == null) {
            throw new RuntimeException("验证码不存在或已过期，请重新获取");
        }
        
        // 验证码是否过期
        long currentTime = System.currentTimeMillis();
        long codeTime = codeInfo.getCreateTime().getTime();
        if ((currentTime - codeTime) / (1000 * 60) > expireMinutes) {
            // 验证码过期，移除
            codeMap.remove(email);
            throw new RuntimeException("验证码已过期，请重新获取");
        }
        
        // 验证码是否匹配
        boolean result = codeInfo.getCode().equals(code);
        if (result) {
            // 验证成功后，移除验证码
            codeMap.remove(email);
            return true;
        } else {
            throw new RuntimeException("验证码错误，请重新输入");
        }
    }
    
    /**
     * 验证码信息类
     */
    private static class CodeInfo {
        private final String code;
        private final Date createTime;
        
        public CodeInfo(String code, Date createTime) {
            this.code = code;
            this.createTime = createTime;
        }
        
        public String getCode() {
            return code;
        }
        
        public Date getCreateTime() {
            return createTime;
        }
    }
} 